/* eslint-disable no-param-reassign */
/* eslint-disable react/no-array-index-key */
/* eslint-disable no-shadow */
/* eslint-disable no-debugger */
/* eslint-disable no-case-declarations */
/* eslint-disable consistent-return */

/**
 * 表单字段控件
 * @author LiAnqi
 * @date 2022-3-22
 * @description
 */

import { Input, Select, TreeSelect, Radio, InputNumber, DatePicker, TimePicker, Switch, Checkbox } from 'antd'
import moment from 'moment'
// import { FCDateRangePicker, UseCodes } from '../../../index'
import NumberRange from './NumberRange'
import SelectAll from './SelectAll'
import { UseCodes } from '@contexts/MainContext'
import { ControlType as TYPE, FORMAT } from '../../config/Constant'
import '../less/FieldControl.less'
import { useEffect, useState } from 'react'
const { TextArea } = Input
const { RangePicker } = DatePicker

function FieldControl(props) {
  const {
    selectmode,
    name,
    value,
    onChange,
    onOpenChange = () => {},
    allowEmpty = [true, true],
    controlType = TYPE.INPUT,
    rules = [],
    options,
    codeKey,
    uselessOptions,
    disabledOptions,
    disabled,
    // select props
    allowClear = true,
    onClear,
    showSearch,
    optionFilterProp,
    filterOption,
    optionTemplate = () => false, //下拉框选项列模板
    //
    ...restProps
  } = props

  const selectRest = { allowClear, onClear, showSearch, optionFilterProp, filterOption, selectmode, }
  const withValueProps = {
    value,
    disabled,
  }
  const unValueProps = {
    disabled,
  }

  const handleInputChange = (e) => {
    onChange(e)
  }

  const handleSelectChange = (value, option) => {
    onChange(value, option)
  }

  const handleTreeSelectChange = (value, label, extra) => {
    onChange(value, label, extra)
  }

  const handleRadioChange = (e) => {
    onChange(e.target.value)
  }

  const handleSwitchChange = (checked, event) => {
    onChange(checked)
  }

  const handleDateRangePickerChange = (params) => {
    onChange(params)
  }

  const dealOptions = () => {
    if (options) return options
    if (codeKey === null) return []
    const opts = UseCodes(codeKey)
    // const opts = []
    const arr = uselessOptions
      ? [...opts]?.filter((item) => [...uselessOptions].every((v) => v !== item.value))
      : opts
    const returnArr = disabledOptions
      ? arr?.map((item) => {
        if (disabledOptions.some((dValue) => dValue === item.value)) {
          item.ifDisabled = true
        }
        return item
      })
      : arr
    return returnArr
  }

  const render = () => {
    const input = (
      <Input
        type="text"
        name={name}
        {...withValueProps}
        onChange={handleInputChange}
        {...restProps}
        allowClear={allowClear}
      />
    )
    switch (controlType) {
      case TYPE.INPUT:
        return input
      case TYPE.TEXTAREA:
        const { rows = 2, maxLength } = restProps
        return (
          <TextArea
            rows={rows}
            maxLength={maxLength}
            {...withValueProps}
            onChange={handleInputChange}
            {...restProps}
          />
        )
      case TYPE.INPUT_NUMBER_RANGE:
        return (<NumberRange />)
      case TYPE.INPUT_NUMBER:
        const { min, max } = restProps
        return (
          <InputNumber
            min={min}
            max={max}
            {...withValueProps}
            onChange={handleInputChange}
            {...restProps}
          />
        )
      case TYPE.INPUT_EMAIL:
        return input
      case TYPE.INPUT_URL:
        return input
      case TYPE.INPUT_PASSWORD:
        return input
      case TYPE.RADIO:
        const rOptions = dealOptions()
        return (
          <Radio.Group
            {...withValueProps}
            onChange={handleRadioChange}
            disabled={disabled}
            {...restProps}
          >
            {rOptions?.map((option, index) => (
              <Radio key={index} value={option.value}>
                {option.label}
              </Radio>
            ))}
          </Radio.Group>
        )
      case TYPE.SWITCH:
        const checked = !!(value === true || value === 1)
        return (
          <Switch
            checked={checked}
            onChange={handleSwitchChange}
            {...unValueProps}
            {...restProps}
          />
        )
      case TYPE.CHECKBOX:
        return (
          <Checkbox defaultValue={value} options={dealOptions()} {...unValueProps} {...restProps} />
        )
      case TYPE.SELECTBOTH:
        const sOptions1 = dealOptions()
        return (
          <Select
            defaultValue={value}
            onChange={handleSelectChange}
            {...withValueProps}
            {...selectRest}
            {...restProps}
            allowClear={allowClear}
            mode={selectmode}
          >
            {sOptions1.map((option, index) => (
              <Select.Option key={index} value={option.value} disabled={option.ifDisabled}>
                {optionTemplate(option) || option.value + '-' + option.label}
              </Select.Option>
            ))}
          </Select>
        )
      case TYPE.SELECTALL:
        return (
          <SelectAll
            defaultValue={value}
            onChange={onChange}
            withValueProps={withValueProps}
            selectRest={selectRest}
            restProps={restProps}
            allowClear={allowClear}
            mode='multiple'
            optionTemplate={optionTemplate}
            dealOptions={dealOptions()}
          />
        )
      case TYPE.SELECT:
        const sOptions = dealOptions()
        return (
          <Select
            defaultValue={value}
            onChange={handleSelectChange}
            {...withValueProps}
            {...selectRest}
            {...restProps}
            allowClear={allowClear}
            mode={selectmode}
            // maxTagCount='responsive'
            // maxTagCount={2}
          >
            {sOptions?.map((option, index) => (
              <Select.Option key={index} value={option.value} disabled={option.ifDisabled}>
                {option.label}
              </Select.Option>
            ))}
          </Select>
        )
      case TYPE.TREESELECT:
        return (
          <TreeSelect 
            defaultValue={value}
            treeData={UseCodes(codeKey)}
            onChange={handleTreeSelectChange}
            showSearch={true}
            treeNodeFilterProp='title'
            treeDefaultExpandAll={true}
            allowClear={allowClear}
            {...withValueProps}
            {...restProps}
          />
        )
      case TYPE.SELECTMULTIPLE:
        const sOptions2 = dealOptions()
        return (
          <Select
            defaultValue={value}
            onChange={handleSelectChange}
            {...withValueProps}
            {...selectRest}
            {...restProps}
            allowClear={allowClear}
            mode='multiple'
          >
            {sOptions2?.map((option, index) => (
              <Select.Option key={index} value={option.value} disabled={option.ifDisabled}>
                {option.label}
              </Select.Option>
            ))}
          </Select>
        )
      case TYPE.DATE_PICKER:
        const { picker } = restProps
        return (
          <DatePicker
            style={{ width: '100%' }}
            picker={picker}
            onChange={onChange}
            value={value ? moment(value, FORMAT.DATE) : null}
            disabled={disabled}
            {...restProps}
          />
        )
      case TYPE.TIME_PICKER:
        return (
          <TimePicker
            style={{ width: '100%' }}
            onChange={onChange}
            defaultValue={value ? moment(value, FORMAT.TIME) : null}
            {...withValueProps}
            {...restProps}
          />
        )
      case TYPE.DATE_RANGE_PICKER:
        return (
          <RangePicker
            style={{ width: '100%' }}
            onChange={handleDateRangePickerChange}
            value={value}
            disabled={disabled}
            {...restProps}
          />
        )
      default:
        return input
    }
  }
  return <>{render()}</>
}

export default FieldControl
